home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / fdimg / oh!.2hd / OH!DEN_B.LZH / TOOLS / KEYWITCH / KW_S200.LZH / w20main.s < prev    next >
Text File  |  1995-03-20  |  24KB  |  938 lines

  1.     .include    w01dos.mac
  2.     .include    w02iocs.mac
  3.     .include    w03const.mac
  4.     .include    w04macro.mac
  5.     .include    w05reloc.mac
  6.     .include    w08id.mac
  7.     .include    w09mes.mac
  8.  
  9. *使用できるスイッチ
  10. *                 -----zyx wvutsrqp onmlkjih gfedcba-
  11. ALLOWED_SWITCHES    equ    %00000001_00011101_01110110_10110010
  12.  
  13.     .text
  14.     .even
  15.  
  16. ********************************
  17. *デバイスドライバの初期化ルーチン
  18. *<a5.l:リクエストヘッダのアドレス
  19. *>d0.l:終了コード
  20. device_main::
  21.     movem.l    d1-d7/a0-a6,-(sp)
  22. *相対アドレッシングのためのベースレジスタの設定
  23.     lea.l    base(pc),a6
  24. *タイトル表示
  25.     moveq.l    #M_CRLF,d4
  26.     bsr    write_message
  27.     moveq.l    #M_TITLE,d4
  28.     bsr    write_message
  29. *デバイスドライバのフラグをセットする
  30.     st.b    (device_flag)r        *デバイスドライバとして組み込まれた
  31. *起動ディレクトリを設定
  32.     movea.l    18(a5),a0        *区切りは0,エンドコードは0,0
  33.     pea.l    (exec_directory)r
  34.     move.l    a0,-(sp)
  35.     DOS    _NAMECK
  36.     addq.w    #8,sp
  37. *スタックエリアを設定
  38.     movea.l    sp,a1
  39.     lea.l    (stack_top)r,sp
  40.     move.l    a1,-(sp)
  41. *パラメータのアドレスを設定
  42. *<a0.l:デバイス名とパラメータの並び(区切りは0,エンドコードは0,0)
  43. search_param_top::
  44.     tst.b    (a0)+
  45.     bne    search_param_top    *デバイス名を読み飛ばす
  46.     lea.l    (device_params)r,a1
  47.     bra    copy_params_next
  48.  
  49. copy_params_loop::
  50.     move.b    #' ',(a1)+        *区切りをスペースにする
  51. copy_params_copy::
  52.     move.b    (a0)+,(a1)+
  53.     bne    copy_params_copy
  54.     subq.w    #1,a1
  55. copy_params_next::
  56.     tst.b    (a0)
  57.     bne    copy_params_loop
  58.     clr.b    (a1)            *エンドコード
  59.     lea.l    (device_params)r,a2
  60. *OPT.2が押されていたら組み込みを中止する
  61.     moveq.l    #M_ABORTED_BY_KEY,d4
  62.     moveq.l    #$0B,d1
  63.     IOCS    _BITSNS
  64.     btst.l    #2,d0
  65.     bne    device_error_exit    *中止
  66. *常駐しているかどうか確認する
  67.     bsr    search_kept1
  68. *パラメータの確認
  69. *  デバイスドライバの場合はパラメータがなくても組み込みます。
  70. *<a2.l:パラメータのアドレス
  71.     bsr    get_switches
  72. *<d6.l:スイッチが1に指定されたビット=1
  73. *<d7.l:スイッチが指定されたビット=1
  74. *<a2.l:環境定義ファイル名の並びの先頭
  75.     moveq.l    #M_UNKNOWN_SWITCH,d4
  76.     move.l    d7,d0
  77.     and.l    #ALLOWED_SWITCHES,d0    *使用できるスイッチだけマスクする
  78.     cmp.l    d7,d0
  79.     bne    device_error_exit    *使用できないスイッチがあるまたはエラー
  80.     move.w    d6,d0
  81.     not.w    d0
  82.     and.w    d7,d0
  83.     btst.l    #'E'-'@',d0
  84.     bne    device_error_exit    *-e0が指定された
  85.     moveq.l    #'r',d0
  86.     btst.l    d0,d7
  87.     beq    device_no_r_switch
  88.     btst.l    d0,d6
  89.     beq    device_no_r_switch
  90.     moveq.l    #M_UNKNOWN_SWITCH,d4    *デバイスドライバは解除できない
  91. *エラーメッセージを表示してデバイス初期化終了
  92. device_error_exit::
  93.     bsr    write_message
  94.     movea.l    (sp)+,sp        *スタックポインタを復元
  95.     movem.l    (sp)+,d1-d7/a0-a6
  96.     move.w    #$5003,d0
  97.     rts
  98.  
  99. ********************************
  100. *-rが指定されていない場合
  101. *<d6.l:スイッチが1に指定されたビット=1
  102. *<d7.l:スイッチが指定されたビット=1
  103. *<a2.l:環境定義ファイル名の並びの先頭
  104. device_no_r_switch::
  105. *既に組み込まれていないか確認
  106.     moveq.l    #M_ALREADY_EXIST,d4
  107.     cmpa.l    a5,a6
  108.     bne    device_error_exit    *デバイスは2回以上登録できない
  109. *スイッチを常駐部分のフラグ領域に展開する
  110.     bsr    expand_switches
  111. *無効なスイッチがないか
  112.     moveq.l    #M_UNKNOWN_SWITCH,d4
  113.     tst.l    d7
  114.     bne    device_error_exit    *無効なスイッチが指定された
  115. *<a2.l:環境定義ファイル名の並びの先頭
  116.     tst.b    (a2)
  117.     beq    device_no_env_name    *環境ファイル名が指定されていない
  118.     st.b    (env_flag)r        *ファイル名があるときは-eを省略できる
  119. device_no_env_name::
  120. ********************************
  121. *走行中のプログラムのメモリ管理ポインタへのハンドルを探す
  122.     bsr    search_prog_hdl
  123.     tst.b    (prog_flag)r
  124.     beq    device_set_prog_9
  125.     tst.l    d4
  126.     bmi    device_error_exit
  127. device_set_prog_9::
  128. ********************************
  129. *環境定義ファイルを読み込む
  130. *<a2.l:環境定義ファイル名の並びの先頭
  131.     movea.l    a6,a4
  132.     bsr    init_table_work        *テーブルのワークを初期化
  133.     tst.b    (env_flag)r
  134.     beq    device_not_load
  135.     movem.l    d6-d7/a4-a5,-(sp)
  136.     bsr    load_environment    *環境定義ファイルを読む
  137.     movem.l    (sp)+,d6-d7/a4-a5
  138.     bne    device_error_exit    *エラーがあった
  139. device_not_load::
  140. ********************************
  141. *ASKを変更する
  142.     bsr    keep_ask        *ASKを変更する
  143.     bmi    device_error_exit    *変更できない
  144. ********************************
  145. *ベクタを変更する
  146.     bsr    set_spurious        *Spurious Interruptを変更する
  147.     bsr    change_vector        *ベクタを変更する
  148. ********************************
  149. *デバイス初期化終了
  150.     movea.l    (sp)+,sp        *スタックポインタを復元
  151.     movem.l    (sp)+,d1-d7/a0-a6
  152.     bra    device_keeper        *変換テーブルを転送してデバイス初期化終了
  153.  
  154. ********************************
  155. *メインルーチン
  156. main::
  157. *相対アドレッシングのためのベースレジスタの設定
  158.     lea.l    base(pc),a6
  159. *タイトル表示
  160.     moveq.l    #M_TITLE,d4
  161.     bsr    write_message
  162. *起動ディレクトリを設定
  163.     lea.l    (prog_head-$80)r,a0    *起動ディレクトリ
  164.     lea.l    (exec_directory)r,a1
  165. copy_directory::
  166.     move.b    (a0)+,(a1)+
  167.     bne    copy_directory
  168. *メモリサイズを設定
  169.     lea.l    (prog_head-$F0)r,a0
  170.     lea.l    prog_tail,a1        *相対アドレスでは届かない
  171.     suba.l    a0,a1
  172.     movem.l    a0-a1,-(sp)
  173.     DOS    _SETBLOCK        *必要な長さに設定する
  174.     addq.w    #8,sp
  175.     moveq.l    #M_MEMORY_SHORTAGE,d4
  176.     tst.l    d0
  177.     bmi    write_and_exit1        *メモリが不足している
  178. *スタックエリアを設定
  179.     lea.l    (stack_top)r,sp
  180. *パラメータのアドレスを設定
  181.     addq.w    #1,a2
  182. *OPT.2が押されていたら組み込みを中止する
  183.     moveq.l    #M_ABORTED_BY_KEY,d4
  184.     moveq.l    #$0B,d1
  185.     IOCS    _BITSNS
  186.     btst.l    #2,d0
  187.     bne    write_and_exit1        *中止
  188. *常駐しているかどうか確認する
  189.     super
  190.     bsr    search_kept2
  191.     user
  192. *コマンドラインの確認
  193. *<a2.l:パラメータのアドレス
  194.     bsr    get_switches
  195.     bne    exist_switches        *スイッチがあるまたはエラー
  196.     moveq.l    #M_USAGE,d4
  197.     tst.b    (a2)
  198.     beq    write_and_exit        *コマンドラインに何も書かれていない
  199. exist_switches::
  200. *<d6.l:スイッチが1に指定されたビット=1
  201. *<d7.l:スイッチが指定されたビット=1
  202. *<a2.l:環境定義ファイル名の並びの先頭
  203.     moveq.l    #M_UNKNOWN_SWITCH,d4
  204.     move.l    d7,d0
  205.     and.l    #ALLOWED_SWITCHES,d0    *使用できるスイッチだけマスクする
  206.     cmp.l    d7,d0
  207.     bne    usage_and_exit1        *使用できないスイッチがあるまたはエラー
  208.     move.w    d6,d0
  209.     not.w    d0
  210.     and.w    d7,d0
  211.     btst.l    #'E'-'@',d0
  212.     bne    usage_and_exit1        *-e0が指定された
  213.     movea.l    a5,a4
  214.     moveq.l    #'r',d0
  215.     bclr.l    d0,d7
  216.     beq    no_r_switch        *-rは指定されていない
  217.     btst.l    d0,d6
  218.     beq    no_r_switch        *-rは指定されていない
  219.     movea.l    a6,a4
  220.     tst.l    d7
  221.     bne    no_r_switch        *-r以外のスイッチが同時に指定された
  222.     tst.b    (a2)
  223.     bne    no_r_switch        *環境定義ファイル名が同時に指定された
  224. ********************************
  225. *常駐を解除する
  226. *<d6.l:スイッチが1に指定されたビット=1
  227. *<d7.l:スイッチが指定されたビット=1
  228. *<a2.l:環境定義ファイル名の並びの先頭
  229. *常駐しているか確認
  230.     moveq.l    #M_NOT_KEPT,d4
  231.     cmpa.l    a5,a6
  232.     beq    write_and_exit1        *常駐していない
  233.     moveq.l    #M_OTHER_VERSION,d4
  234.     cmp.l    (program_id+4)r,d5
  235.     bne    write_and_exit1        *バージョンが違うので解除できない
  236.     moveq.l    #M_CANNOT_RELEASE_DEVICE,d4
  237.     lea.l    (device_flag)rr,a1
  238.     IOCS    _B_BPEEK
  239.     tst.b    d0
  240.     bne    write_and_exit1        *デバイスドライバなので解除できない
  241. *ASKの変更を復元できるどうか確かめる
  242.     tst.b    (ask_flag)rr
  243.     beq    not_recur_ask_1        *ASKは変更されていない
  244.     super
  245.     move.l    (ask_flag_bits)rr,d0
  246.     bsr    recur_ask_test        *ASKの変更を復元できるかどうか確かめる
  247.     user
  248.     tst.l    d4
  249.     bmi    write_and_exit1        *ASKの変更を復元できない
  250. not_recur_ask_1::
  251. *キーボード関係を初期化する
  252.     super
  253.     move.b    LEDSNS.w,d1
  254.     bsr    _key_init        *自分自身の何も設定されていない状態
  255. *ベクタを復元する
  256.     lea.l    (vector_table)rr,a0    *ベクタ管理テーブル
  257.     moveq.l    #M_CANNOT_RELEASE,d4
  258.     moveq.l    #0,d3            *ベクタがROMを指している=-1
  259.     move.l    #$00FFFFFF,d2
  260.     di
  261.     move.w    (a0)+,d0
  262. release_loop_1::
  263.     bsr    condrv_check        *KEY_INITでCONDRVか
  264.     beq    release_next        *CONDRVを指しているのでスキップ
  265.     movea.w    d0,a1
  266.     move.l    d2,d0            *d2=$00FFFFFF
  267.     and.l    (a1),d0            *現在のアドレス
  268.     cmp.l    #$00FC0000,d0
  269.     blo    release_not_rom        *ROMではない
  270.     moveq.l    #-1,d3            *ベクタがROMを指している
  271.     bra    release_next        *ROMなら比較せずに次へ
  272.  
  273. release_not_rom::
  274.     move.l    d2,d1            *d2=$00FFFFFF
  275.     and.l    4(a0),d1        *指しているはずのアドレス
  276.     cmp.l    d0,d1            *現在のアドレスと比較
  277.     bne    release_error        *ベクタが変更されていて解除できない
  278. release_next::
  279.     addq.w    #8,a0
  280.     move.w    (a0)+,d0
  281.     bne    release_loop_1
  282.     moveq.l    #0,d4
  283.     lea.l    (vector_table)rr,a0
  284.     move.w    (a0)+,d0
  285. release_loop_2::
  286.     movea.w    d0,a1
  287.     cmpi.b    #$FC,1(a1)        *現在のアドレスの上から2バイト目
  288.     bhs    release_vector_next    *ROMならスキップ
  289.     bsr    condrv_check        *KEY_INITでCONDRVか
  290.     bne    release_vector_go    *違う
  291.     move.l    (a0),6(a1)        *CONDRVの元のベクタを復元する
  292.     cache_flush            *キャッシュフラッシュ
  293.     bra    release_vector_next
  294.  
  295. release_vector_go::
  296.     movea.w    d0,a1
  297.     move.l    (a0),(a1)        *ベクタを復元
  298. release_vector_next::
  299.     addq.w    #8,a0
  300.     move.w    (a0)+,d0
  301.     bne    release_loop_2
  302. release_error::
  303.     ei
  304.     user
  305.     tst.l    d4
  306.     bmi    write_and_exit1        *ベクタが変更されていて解除できない
  307.     tst.l    d3
  308.     beq    release_no_alart
  309.     moveq.l    #M_ALART_ROM_VECTOR,d4
  310.     bsr    write_message        *ROMを指していた場合は警告する
  311. release_no_alart::
  312. *ASKの変更を復元する
  313.     tst.b    (ask_flag)rr
  314.     beq    not_recur_ask_2        *ASKは変更されていない
  315.     super
  316.     move.l    (ask_flag_bits)rr,d0
  317.     bsr    recur_ask        *ASKの変更を復元する
  318.     user
  319.     clr.b    (ask_flag)rr        *常駐解除に失敗した場合のため
  320. not_recur_ask_2::
  321. *常駐部分をメモリから削除する
  322.     moveq.l    #M_ALLOCATION_ERROR,d4
  323.     move.l    (alloc_point)rr,d0
  324.     beq    @f
  325.     move.l    d0,-(sp)
  326.     DOS    _MFREE
  327.     addq.w    #4,sp
  328.     tst.l    d0
  329.     bmi    write_and_exit1        *メモリの開放に失敗した
  330. @@:    pea.l    (prog_head-$100+$10)rr
  331.     DOS    _MFREE
  332.     addq.w    #4,sp
  333.     tst.l    d0
  334.     bmi    write_and_exit1        *メモリの開放に失敗した
  335. *正常終了
  336.     moveq.l    #M_RELEASED,d4
  337. *メッセージを表示して正常終了
  338. *<d4.w:メッセージの番号
  339. write_and_exit:;
  340.     bsr    write_message
  341.     DOS    _EXIT
  342.  
  343. *メッセージと使用法を表示してエラー終了
  344. *<d4.w:メッセージの番号
  345. usage_and_exit1::
  346.     bsr    write_message
  347.     moveq.l    #M_USAGE,d4
  348. *メッセージを表示してエラー終了
  349. *<d4.w:メッセージの番号
  350. write_and_exit1::
  351.     bsr    write_message
  352.     move.w    #1,-(sp)
  353.     DOS    _EXIT2
  354.  
  355. ********************************
  356. *-rが指定されていないか、-rと同時に他のスイッチか環境定義ファイル名が指定された
  357. *<d6.l:スイッチが1に指定されたビット=1
  358. *<d7.l:スイッチが指定されたビット=1
  359. *<a2.l:環境定義ファイル名の並びの先頭
  360. *<a4.l:-rが指定されていない=a5/-rが指定された=a6
  361. no_r_switch::
  362. *<a2.l:環境定義ファイル名の並びの先頭
  363.     tst.b    (a2)
  364.     beq    no_env_name        *環境ファイル名が指定されていない
  365.     st.b    (env_flag)r        *ファイル名があるときは-eを省略できる
  366. no_env_name::
  367. *既に常駐していないか確認
  368.     cmpa.l    a5,a6
  369.     bne    change_switches        *既に常駐している
  370. *スイッチを常駐部分のフラグ領域に展開する
  371.     bsr    expand_switches
  372. *無効なスイッチがないか
  373.     moveq.l    #M_UNKNOWN_SWITCH,d4
  374.     tst.l    d7
  375.     bne    usage_and_exit1        *無効なスイッチが指定された
  376. ********************************
  377. *走行中のプログラムのメモリ管理ポインタへのハンドルを探す
  378.     bsr    search_prog_hdl
  379.     tst.b    (prog_flag)r
  380.     beq    set_prog_9
  381.     tst.l    d4
  382.     bmi    write_and_exit1
  383. set_prog_9::
  384. ********************************
  385. *環境定義ファイルを読み込む
  386. *<a2.l:環境定義ファイル名の並びの先頭
  387. *<a4.l:-rが指定されていない=a5/-rが指定された=a6
  388.     bsr    init_table_work        *テーブルのワークを初期化
  389.     tst.b    (env_flag)r
  390.     beq    not_load
  391.     movem.l    d6-d7/a4-a5,-(sp)
  392.     bsr    load_environment    *環境定義ファイルを読む
  393.     movem.l    (sp)+,d6-d7/a4-a5
  394.     bne    write_and_exit1        *エラーがあった
  395. not_load::
  396. ********************************
  397. *ASKを変更する
  398.     super
  399.     bsr    keep_ask        *ASKを変更する
  400.     user
  401.     tst.l    d4
  402.     bmi    write_and_exit1        *変更できない
  403. ********************************
  404. *ベクタを変更する
  405.     super
  406.     bsr    set_spurious        *Spurious Interruptを変更する
  407.     bsr    change_vector        *ベクタを変更する
  408.     user
  409. ********************************
  410. *常駐終了
  411.     moveq.l    #M_KEPT,d4
  412.     bsr    write_message
  413.     bra    keeper            *変換テーブルを転送して常駐終了
  414.  
  415. ********************************
  416. *既に常駐している場合
  417. *<d6.l:スイッチが1に指定されたビット=1
  418. *<d7.l:スイッチが指定されたビット=1
  419. *<a2.l:環境定義ファイル名の並びの先頭
  420. *<a4.l:-rが指定されていない=a5/-rが指定された=a6
  421. change_switches::
  422. *常駐部分のバージョンの確認
  423.     moveq.l    #M_OTHER_VERSION2,d4
  424.     cmp.l    (program_id+4)r,d5    *バージョンチェック
  425.     bne    write_and_exit1        *バージョンが違うので変更できない
  426. ********************************
  427. *走行中のプログラムのメモリ管理ポインタへのハンドルを探す
  428.     super
  429.     bsr    search_prog_hdl
  430.     user
  431.     btst.l    #'P'-'@',d6
  432.     beq    change_prog_hdl_9
  433.     tst.l    d4
  434.     bmi    write_and_exit1
  435. change_prog_hdl_9::
  436. ********************************
  437. *環境定義ファイルを読み込む
  438. *<a2.l:環境定義ファイル名の並びの先頭
  439. *<a4.l:-rが指定されていない=a5/-rが指定された=a6
  440.     super
  441.     bsr    init_table_work        *テーブルのワークを初期化
  442.     user
  443.     btst.l    #'E'-'@',d7
  444.     beq    not_load2
  445.     btst.l    #'E'-'@',d6
  446.     beq    not_load2
  447.     movem.l    d6-d7/a4-a5,-(sp)
  448.     bsr    load_environment    *環境定義ファイルを読む
  449.     movem.l    (sp)+,d6-d7/a4-a5
  450.     bne    write_and_exit1        *エラーがあった
  451. not_load2::
  452. ********************************
  453. *-aは変更できる
  454. change_ask::
  455.     btst.l    #'A'-'@',d7
  456.     beq    change_ask_end        *-aが指定されていない
  457.     btst.l    #'A'-'@',d6
  458.     beq    change_ask_off        *-a0
  459. *-a1
  460. change_ask_on::
  461.     lea.l    (ask_flag)rr,a1
  462.     IOCS    _B_BPEEK
  463.     tst.b    d0
  464.     bne    change_ask_end
  465. *-a0から-a1にする
  466.     super
  467.     move.l    (ask_flag_bits)rr,d0
  468.     bsr    patch_ask_test        *ASKを変更できるかどうか確かめる
  469.     bmi    change_ask_on_error    *変更できない
  470.     bsr    patch_ask        *ASKを変更する
  471. change_ask_on_error::
  472.     user
  473.     tst.l    d4
  474.     bmi    write_and_exit1        *エラーあり
  475.     bra    change_ask_end
  476.  
  477. *-a0
  478. change_ask_off::
  479.     lea.l    (ask_flag)rr,a1
  480.     IOCS    _B_BPEEK
  481.     tst.b    d0
  482.     beq    change_ask_end
  483. *-a1から-a0にする
  484.     super
  485.     move.l    (ask_flag_bits)rr,d0
  486.     bsr    recur_ask_test        *ASKを復元できるかどうか確かめる
  487.     bmi    change_ask_off_error    *復元できない
  488.     bsr    recur_ask        *ASKを復元する
  489. change_ask_off_error
  490.     user
  491.     tst.l    d4
  492.     bmi    write_and_exit1        *エラーあり
  493. change_ask_end::
  494. *スイッチを常駐部分のフラグ領域に展開する
  495. *  デバイスドライバの場合があるので、スーパーバイザモードで書き換える必要がある。
  496. *  無効なスイッチがあってもリトライできない。
  497.     super
  498.     bclr.l    #'E'-'@',d7
  499.     bsr    expand_switches
  500.     user
  501. *環境定義を変更する
  502.     super
  503.     bsr    renew_table_work    *テーブルのワークを常駐部に移動
  504.     user
  505. *キーボード関係を初期化してから正常終了
  506.     super
  507.     move.b    LEDSNS.w,d1
  508.     jsr    (_key_init)rr        *常駐部分のルーチンを呼ぶ
  509.     user
  510.     moveq.l    #M_CHANGED,d4
  511.     bra    write_and_exit
  512.  
  513. ********************************
  514. *ASKを変更する
  515. *  スーパーバイザモードで呼び出すこと。
  516. *<a6.l:base
  517. *>d4.l:エラーコード
  518. keep_ask::
  519.     moveq.l    #0,d4
  520.     tst.b    (ask_flag)r
  521.     beq    keep_ask_end        *ASKを変更しない
  522.     move.l    (ask_flag_bits_work)r,d0
  523.     bsr    patch_ask_test        *ASKを変更できるかどうか確かめる
  524.     bmi    keep_ask_end        *変更できない
  525.     bsr    patch_ask        *ASKを変更する
  526. keep_ask_end::
  527.     tst.l    d4
  528.     rts
  529.  
  530. ********************************
  531. *ベクタを変更する
  532. *  スーパーバイザモードで呼び出すこと。
  533. *  CONDRVがKEY_INITをフックしている場合はCONDRV側を変更します。
  534. *<a6.l:base
  535. *?d0/a0-a1
  536. change_vector::
  537.     lea.l    (vector_table)r,a0    *ベクタ管理テーブル
  538.     di
  539.     move.w    (a0)+,d0
  540. change_vector_loop::
  541.     bsr    condrv_check        *KEY_INITでCONDRVか
  542.     bne    change_vector_go    *違う
  543.     move.l    6(a1),(a0)+        *CONDRVが保存していた元のベクタ
  544.     move.l    (a0)+,6(a1)        *CONDRVからKeyWitchにジャンプさせる
  545.     cache_flush            *キャッシュフラッシュ
  546.     bra    change_vector_next
  547.  
  548. change_vector_go::
  549.     movea.w    d0,a1
  550.     move.l    (a1),(a0)+        *元のベクタを保存
  551.     move.l    (a0)+,(a1)        *新しいベクタを設定
  552. change_vector_next::
  553.     move.w    (a0)+,d0
  554.     bne    change_vector_loop
  555.     ei
  556.     rts
  557.  
  558. ********************************
  559. *ベクタがKEY_INITならばCONDRVが組み込まれているか確認する
  560. *  スーパーバイザモードで呼び出すこと
  561. *<d0.w:ベクタアドレス
  562. *>a1.l:ベクタがKEY_INITならばそのアドレス
  563. *>z:CONDRVならばeq,違えばne
  564. condrv_check::
  565.     cmp.w    #$0400+_KEY_INIT*4,d0
  566.     bne    condrv_check_end    *KEY_INIT以外
  567.     movea.w    d0,a1
  568.     movea.l    (a1),a1            *KEY_INITのアドレス
  569.     cmpi.l    #'hmk*',-4(a1)        *CONDRVチェック
  570.     bne    condrv_check_end
  571.     cmpi.w    #$6100,(a1)        *bsr.w
  572.     bne    condrv_check_end
  573.     cmpi.w    #$4EF9,4(a1)        *jmp ?.l
  574. condrv_check_end::
  575.     rts
  576.  
  577. ********************************
  578. *Spurious InterruptをROM内のrteに変更する
  579. *  スーパーバイザモードで呼び出すこと。
  580. *?d0/a0
  581. set_spurious::
  582.     move.w    #$4E73,d0        *rte
  583.     cmpi.b    #$FC,SPUINT*4+1.w
  584.     blo    set_spurious_rom    *RAMを指している可能性がある
  585.     movea.l    SPUINT*4.w,a0
  586.     cmp.w    (a0),d0
  587.     beq    set_spurious_end    *既にROM内のrteを指している
  588. set_spurious_rom::
  589.     lea.l    $FC0000.l,a0
  590. set_spurious_search::
  591.     cmp.w    (a0)+,d0        *ROMからrteを探す
  592.     bne    set_spurious_search
  593.     subq.w    #2,a0
  594.     move.l    a0,SPUINT*4.w
  595. set_spurious_end::
  596.     rts
  597.  
  598. ********************************
  599. *常駐しているかどうか確認する(割り込みベクタとデバイスドライバのみ)
  600. *  スーパーバイザモードで呼び出すこと。
  601. *<a6.l:base
  602. *>d5.l:常駐している=常駐部分のバージョン/常駐していない=自分自身のバージョン
  603. *>a5.l:常駐している=常駐部分のbase/常駐していない=自分自身のbase
  604. *?d0-d1/d5/a1/a5
  605. search_kept1::
  606. *キー入力割り込みベクタを確認する
  607.     move.l    (KEYINT*4).w,d0
  608.     and.l    #$00FFFFFF,d0
  609.     movea.l    d0,a5            *キー入力割り込みベクタ
  610.     lea.l    base-key_int(a5),a5    *常駐部分のbase
  611.     move.l    (program_id)rr,d0    *常駐部分のフラグ
  612.     cmp.l    (program_id)r,d0    *フラグを比較する
  613.     bne    not_kept_keyint        *常駐していないかベクタが変更されている
  614.     move.l    (program_id+4)rr,d5    *常駐部分のバージョン
  615.     rts
  616.  
  617. not_kept_keyint::
  618. *先頭のNULデバイスを探す
  619. search_nul::
  620.     move.w    #'NU',d1
  621.     lea.l    (prog_head)r,a5
  622.     move.l    a5,d0
  623.     lea.l    ($6800).w,a5        *Humanの先頭
  624.     sub.l    a5,d0            *探す部分の長さ
  625.     and.l    #$00FFFFFF,d0
  626.     lsr.l    #1,d0
  627.     subq.l    #1,d0
  628.     swap.w    d0
  629. search_nul_high_loop::
  630.     swap.w    d0
  631. search_nul_loop::
  632.     cmp.w    (a5)+,d1        *1~2バイト目をチェック
  633.     dbeq    d0,search_nul_loop
  634.     bne    search_nul_high_next
  635.     cmpi.w    #'L ',(a5)        *3~4バイト目をチェック
  636.     dbeq    d0,search_nul_loop
  637.     bne    search_nul_high_next
  638.     cmpi.l    #'    ',2(a5)        *5~8バイト目をチェック
  639.     dbeq    d0,search_nul_loop
  640.     bne    search_nul_high_next
  641.     cmpi.w    #$8024,-2-4-4-2(a5)    *デバイスタイプをチェック
  642.     dbeq    d0,search_nul_loop
  643.     beq    search_nul_found    *見つかった
  644. search_nul_high_next::
  645.     swap.w    d0
  646.     dbra    d0,search_nul_high_loop
  647.     bra    not_kept        *見つからない
  648.  
  649. search_nul_found::
  650.     lea.l    -2-4-4-2-4(a5),a5    *デバイスヘッダ
  651. *デバイスドライバを辿る
  652. *<a5.l:先頭のNULデバイスのデバイスヘッダ
  653. search_device_loop::
  654.     move.l    device_name-prog_head(a5),d0    *デバイス名(1~4バイト目)
  655.     cmp.l    (device_name)r,d0
  656.     bne    search_device_next    *違う
  657.     move.l    device_name+4-prog_head(a5),d0    *デバイス名(5~8バイト目)
  658.     cmp.l    (device_name+4)r,d0
  659.     bne    search_device_next    *違う
  660.     move.l    program_id-prog_head(a5),d0    *常駐部分のフラグ
  661.     cmp.l    (program_id)r,d0
  662.     beq    search_device_found    *見つかった
  663. search_device_next::
  664.     move.l    (a5),d0            *次のデバイスヘッダ
  665.     movea.l    d0,a5
  666.     addq.l    #1,d0
  667.     bne    search_device_loop
  668.     bra    not_kept        *見つからない
  669.  
  670. search_device_found::
  671.     lea.l    base-prog_head(a5),a5    *常駐部分のbase
  672.     move.l    (program_id+4)rr,d5    *常駐部分のバージョン
  673.     rts
  674.  
  675. ********************************
  676. *常駐しているかどうか確認する(すべて確認)
  677. *  スーパーバイザモードで呼び出すこと。
  678. *  自分自身がデバイスドライバのときは使わないこと。
  679. *<a6.l:base
  680. *>d5.l:常駐している=常駐部分のバージョン/常駐していない=自分自身のバージョン
  681. *>a5.l:常駐している=常駐部分のbase/常駐していない=自分自身のbase
  682. *?d0-d1/d5/a5
  683. search_kept2::
  684.     bsr    search_kept1        *割り込みとデバイスドライバをサーチ
  685.     cmpa.l    a5,a6
  686.     bne    search_kept2_end    *見つかった
  687.     move.l    #$00FFFFFF,d1
  688. *手前を探す
  689.     lea.l    (prog_head-$100)r,a5
  690.     bra    lower_start
  691.  
  692. lower_next::
  693.     bsr    search_kept2_check    *確認ルーチン
  694. lower_start::
  695.     move.l    (a5),d0            *直前のメモリ管理ポインタ
  696.     bne    lower_next
  697. *先を探す
  698.     lea.l    (prog_head-$100)r,a5
  699.     bra    higher_start
  700.  
  701. higher_next::
  702.     bsr    search_kept2_check    *確認ルーチン
  703. higher_start::
  704.     move.l    12(a5),d0        *直後のメモリ管理ポインタ
  705.     bne    higher_next
  706. *見つからない
  707. not_kept::
  708.     movea.l    a6,a5            *自分自身のbase
  709.     move.l    (program_id+4)r,d5    *自分自身のバージョン
  710. search_kept2_end::
  711.     rts
  712.  
  713. *確認ルーチン
  714. search_kept2_check::
  715.     movea.l    d0,a5
  716.     move.l    8(a5),d0        *メモリブロックのエンドアドレス
  717.     sub.l    a5,d0            *メモリブロックの長さ
  718.     and.l    d1,d0            *d1=$00FFFFFF
  719.     cmp.l    #keep_tail-(prog_head-$100),d0
  720.     blo    search_kept2_next    *ブロックが短すぎる
  721.     move.l    program_id-(prog_head-$100)(a5),d0    *常駐部分のフラグ
  722.     cmp.l    (program_id)r,d0
  723.     bne    search_kept2_next    *違う
  724.     lea.l    base-(prog_head-$100)(a5),a5    *常駐部分のbase
  725.     move.l    (program_id+4)rr,d5    *常駐部分のバージョン
  726.     addq.w    #4,sp            *見つかった
  727. search_kept2_next::
  728.     rts
  729.  
  730. ********************************
  731. *走行中のプログラムのメモリ管理ポインタへのハンドルを探す
  732. *  スーパーバイザモードで呼び出すこと。
  733. *<a5.l:常駐部分のbase
  734. *>d4.l:エラーコード
  735. *?d0-d1/d4/a1
  736. search_prog_hdl::
  737.     moveq.l    #0,d4
  738.     move.l    d4,(prog_hdl)rr
  739.     moveq.l    #M_UNKNOWN_HUMAN,d4
  740.     move.w    #_GETPDB~0,-(sp)
  741.     DOS    _INTVCG
  742.     addq.w    #2,sp
  743.     movea.l    d0,a1            *_GETPDBの先頭
  744.     IOCS    _B_WPEEK        *先頭の命令を確認
  745.     cmp.w    #$2079,d0        *movea.l abs.l,a0
  746.     bne    search_prog_hdl_end    *失敗
  747.     IOCS    _B_LPEEK
  748.     move.l    d0,d1
  749.     lea.l    ($1c00).w,a1        *アロケート可能なメモリの上限
  750.     IOCS    _B_LPEEK
  751.     cmp.l    d0,d1            *念のためアクセス可能か調べる
  752.     bcc    search_prog_hdl_end    *失敗
  753.     DOS    _VERNUM
  754.     cmp.w    #$0300,d0
  755.     bcc    search_prog_hdl_get3
  756.     DOS    _GETPDB~0
  757.     bra    search_prog_hdl_getend
  758.  
  759. search_prog_hdl_get3::
  760.     DOS    _GETPDB
  761. search_prog_hdl_getend::
  762.     movea.l    d0,a0
  763.     lea.l    -16(a0),a0        *自分のメモリ管理ポインタ
  764.     movea.l    d1,a1
  765.     IOCS    _B_LPEEK
  766.     cmp.l    a0,d0            *現在のプログラムを指しているか
  767.     bne    search_prog_hdl_end    *失敗
  768.     move.l    d1,(prog_hdl)rr        *メモリ管理ポインタへのハンドル
  769.     moveq.l    #0,d4
  770. search_prog_hdl_end::
  771.     tst.l    d4
  772.     rts
  773.  
  774. ********************************
  775. *スイッチを常駐部分のフラグ領域に展開する
  776. *  スーパーバイザモードで呼び出すこと。
  777. *<d6.l:スイッチが1に指定されたビット=1
  778. *<d7.l:スイッチが指定されたビット=1
  779. *<a5.l:常駐部分のbase
  780. *<a6.l:自分自身のbase
  781. *>d7.l:無効なスイッチがない=0
  782. *>z:無効なスイッチがない=1
  783. *?d0-d1/d7/a0
  784. expand_switches::
  785.     lea.l    (expand_switches_table)r,a0
  786.     bra    expand_switches_next
  787.  
  788. expand_switches_loop::
  789.     move.w    (a0)+,d1
  790.     bclr.l    d0,d7
  791.     beq    expand_switches_next
  792.     btst.l    d0,d6
  793.     sne.b    (a5,d1.w)
  794. expand_switches_next::
  795.     move.w    (a0)+,d0
  796.     bne    expand_switches_loop
  797.     tst.l    d7
  798.     rts
  799.  
  800. expand_switches_table::
  801.     .dc.w    'a',ask_flag-base
  802.     .dc.w    'b',extend_flag-base
  803.     .dc.w    'c',click_flag-base
  804.     .dc.w    'd',delay_flag-base
  805.     .dc.w    'e',env_flag-base
  806.     .dc.w    'f',full_flag-base
  807.     .dc.w    'i',lock_flag-base
  808.     .dc.w    'j',joykey_flag-base
  809.     .dc.w    'l',led_flag-base
  810.     .dc.w    'm',meta_flag-base
  811.     .dc.w    'n',repeat_flag-base
  812.     .dc.w    'p',prog_flag-base
  813.     .dc.w    's',stop_flag-base
  814.     .dc.w    't',tvkey_flag-base
  815.     .dc.w    'v',view_flag-base
  816.     .dc.w    'x',exchange_flag-base
  817.     .dc.w    0
  818.  
  819. ********************************
  820. *スイッチの取得
  821. *<a2.l:コマンドラインの先頭
  822. *>d6.l:スイッチが1に指定されたビット=1
  823. *>d7.l:スイッチが指定されたビット=1,エラーのときは最上位ビット=1
  824. *>a2.l:スイッチ以外の文字列の並びの先頭アドレス
  825. *>n:エラー=1
  826. *>z:エラーなしでスイッチの指定がある=0
  827. *?d0-d1/d6-d7/a1-a2
  828. get_switches::
  829.     lea.l    (get_switches_work)r,a1    *スイッチ以外の文字列のワーク
  830.     moveq.l    #0,d7
  831.     moveq.l    #0,d6
  832. get_switches_loop::
  833.     move.b    (a2)+,d0        *ワードの先頭の文字
  834.     beq    get_switches_end    *終わり
  835.     bsr    is_space
  836.     beq    get_switches_loop    *空白
  837. */はスイッチと認めない
  838. *    cmp.b    #'/',d0
  839. *    beq    get_switches_switches
  840.     cmp.b    #'-',d0
  841.     bne    get_switches_name    *スイッチではない
  842. get_switches_switches::
  843.     move.b    (a2)+,d0        *スイッチの文字
  844. get_switches_alpha::
  845. *スイッチに使える文字はアルファベットのみ
  846.     or.b    #$20,d0
  847.     cmp.b    #'a',d0
  848.     blo    get_switches_error    *無効なスイッチ
  849.     cmp.b    #'z',d0
  850.     bhi    get_switches_error    *無効なスイッチ
  851.     move.b    d0,d1            *スイッチの文字
  852.     bset.l    d1,d7
  853.     bset.l    d1,d6            *デフォルトは1
  854.     move.b    (a2)+,d0        *スイッチの直後の文字
  855.     beq    get_switches_end    *終わり
  856.     bsr    is_space
  857.     beq    get_switches_loop    *空白
  858.     cmp.b    #'0',d0
  859.     beq    get_switches_zero    *0が指定された
  860.     cmp.b    #'1',d0
  861.     beq    get_switches_tail    *1が指定された
  862. *スイッチは連続して指定できる
  863.     bra    get_switches_alpha
  864.  
  865. *0が指定された
  866. get_switches_zero::
  867.     bclr.l    d1,d6
  868. get_switches_tail::
  869.     move.b    (a2)+,d0        *0または1の直後の文字
  870.     beq    get_switches_end    *終わり
  871.     bsr    is_space
  872.     beq    get_switches_loop    *空白
  873. *スイッチは連続して指定できる
  874.     bra    get_switches_alpha
  875.  
  876. *スイッチ以外の文字列
  877. get_switches_name::
  878.     move.b    d0,(a1)+
  879.     move.b    (a2)+,d0        *ワードの次の文字
  880.     beq    get_switches_end    *終わり
  881.     bsr    is_space
  882.     bne    get_switches_name
  883. get_switches_name_end::
  884.     clr.b    (a1)+            *スイッチ以外の文字列の区切り
  885.     bra    get_switches_loop
  886.  
  887. *無効なスイッチ
  888. get_switches_error::
  889.     bset.l    #31,d7            *最上位ビットを1にする
  890. get_switches_end::
  891.     clr.b    (a1)+            *スイッチ以外の文字列のエンドコード
  892.     clr.b    (a1)
  893.     lea.l    (get_switches_work)r,a2    *スイッチ以外の文字列のワーク
  894.     tst.l    d7
  895.     rts
  896.  
  897. *空白か
  898. *<d0.b:文字コード
  899. *>z:空白=1
  900. is_space::
  901.     cmp.b    #' ',d0
  902.     beq    is_space_end
  903.     cmp.b    #9,d0
  904. is_space_end::
  905.     rts
  906.  
  907.     .bss
  908.  
  909. ********************************
  910. *起動ディレクトリ
  911. exec_directory::
  912.     .ds.b    92            *_NAMECKバッファなので91バイト以上必要
  913.  
  914. ********************************
  915. *デバイスドライバのパラメータの文字列
  916. device_params::
  917.     .ds.b    260            *区切りは空白
  918.  
  919. ********************************
  920. *環境定義ファイル名の並び
  921. get_switches_work::
  922.     .ds.b    260            *区切りは0,エンドコードは0,0
  923.  
  924. ********************************
  925. *常駐部分が使わない各種フラグ
  926. env_flag::
  927.     .dc.b    0            *環境定義ファイルを読み込む=-1
  928. view_flag::
  929.     .dc.b    0            *状態を表示する=-1
  930.  
  931. ********************************
  932. *スタックエリア
  933.     .even
  934.     .ds.b    8*1024
  935. stack_top::
  936.  
  937.     .end    main
  938.